#ifndef TREE_H
#define TREE_H

#include "treenode.h"

template<typename T>
class Tree
{
public:
    Tree(TreeNode<T> * _root)
    {
        root = _root;
    }

    ~Tree()
    {
        if (root)
        {
            delete root;
        }
    }

    TreeNode<T> * getRoot(){return root;}

    void visitTreePreOrder(void(*visit)(TreeNode<T> * )) const
    {
        visitTreePreOrder(root, visit);
    }

    void visitTreePostOrder(void(*visit)(TreeNode<T> * )) const
    {
        visitTreePostOrder(root, visit);
    }

    void visitTreePreOrder(TreeNode<T> * root, void(*visit)(TreeNode<T> * )) const
    {
        if (root != NULL)
        {
            visit(root);
            for (int i = 0; i < root->getNumChild(); i++)
            {
                visitTreePreOrder(root->getChild(i), visit);
            }
        }
    }

    void visitTreePostOrder(TreeNode<T> * root, void(*visit)(TreeNode<T> *)) const
    {
        if (root != NULL)
        {
            visit(root);
            for (int i = root->getNumChild() - 1; i >= 0; i--)
            {
                visitTreePreOrder(root->getChild(i), visit);
            }
        }
    }

private:
    TreeNode<T> * root;
};

#endif // TREE_H
